package com.wtgroup.demo.common.judge;

import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;

import com.wtgroup.demo.mianshi.其他.lambda.D;

import lombok.Getter;
import lombok.Setter;

public class Testme<D, R> {
    /**
     * 迭代次数 , 默认 1
     */
    @Setter
    @Getter
    private int iterCount = 1;
    private D data;
    private Function<D, R> meFn;
    private Function<D, R> referFn;
    /**
     * 一个比较用例不等, 即退出. 默认 false.
     */
    @Setter
    @Getter
    private boolean failFast;
    private StatInfo statInfo;

    public static <D, R> Testme<D, R> given(Supplier<D> data) {
        return given(data, 1, false);
    }

    public static <D, R> Testme<D, R> given(Supplier<D> data, int iterCount, boolean failFast) {
        Testme<D, R> tester = new Testme<>();
        tester.data = data.get();
        return tester;
    }

    public Testme<D, R> me(Function<D, R> meFn) {
        this.meFn = meFn;
        return this;
    }

    public Testme<D, R> refer(Function<D, R> referFn) {
        this.referFn = referFn;
        return this;
    }

    public void testing(BiFunction<R, R, Boolean> test) {
        int ok = 0;
        int fail = 0;
        int i = 0;
        for (; i < iterCount; i++) {
            R r1 = meFn.apply(data);
            R r2 = referFn.apply(data);
            boolean t = test.apply(r1, r2);

            if (t) {
                ok++;
            } else {
                fail++;
                if (this.failFast) {
                    i++;
                    break;
                }
            }
        }

        StatInfo info = new StatInfo();
        info.iter = i;
        info.fail = fail;
        info.success = ok;

        this.statInfo = info;

        print();

        // return this;
    }

    public void print() {
        System.out.println(this.statInfo);
    }

    static class StatInfo {
        int success;
        int fail;
        int iter;

        @Override
        public String toString() {
            return "success: " + success +
                    ", fail: " + fail +
                    ", iter: " + iter;
        }
    }
}
